home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS04.ADF
/
image.ed
/
event7.c
< prev
next >
Wrap
C/C++ Source or Header
|
1985-10-26
|
38KB
|
1,071 lines
/************* Event7.c ******************/
#include "intuall.h"
#include "imageedit.h"
#include "my.dos.defines.h"
#include "saveformat.h"
#define SLIDERGADGETS 0x64
#define MODIFYRED 0
#define MODIFYGREEN 1
#define MODIFYBLUE 2
#define TXHEIGHT80 8
#define TXHEIGHT60 9
/* topaz.font height 9 is the 60 column text font in system */
/* topaz.font height 8 is the 80 column font */
SHORT txfont; /* if 80, use topaz 80, if 60 use topaz 60 */
SHORT txmode; /* if 1, use jam1, if 2, use jam2 */
SHORT settxcolor;
struct TextAttr modfontattr; /* font structure which I use, aside
* from intuition's use
*/
struct TextFont *myfontptr; /* my font pointer returned by openfont */
extern struct TextFont *OpenFont();
SHORT depth; /* this may have to be moved somewhere else */
extern struct ViewPort *vp;
#define SETPRIMARY 1
#define SETBACKGROUND 0
SHORT color_being_modified;
extern struct BitMap smallbitmap;
extern struct RastPort smallrastport;
extern struct Gadget colorgadget[];
extern struct MsgPort *timerport;
extern struct IOStdReq *timermsg;
struct MsgPort *animtimerport;
struct IOStdReq *animtimermsg;
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
#define SECONDS io_Actual
#define MICROSECONDS io_Length
extern doclick();
extern erase_edit();
extern struct RastPort *rp;
extern USHORT class;
extern USHORT code;
extern USHORT qualifier;
extern struct Window *w;
extern struct frame f[];
extern SHORT selected;
extern struct RastPort undorastport;
extern USHORT mode;
extern struct Requester myrequest;
extern struct Requester dosrequest;
extern struct IntuiText dosreqtext[];
extern struct IntuiText dostext[];
extern struct IntuiText ncrt[];
extern struct Requester textrequest;
extern BYTE dosname[];
extern struct IntuiText textreqtext[];
extern struct Gadget trg[];
extern struct StringInfo textstringstuff;
extern UBYTE textstring[];
extern struct Requester newcolorrequest;
extern struct PropInfo myslider[];
extern struct PropInfo textslider;
extern SHORT framewidth, frameheight;
extern SHORT timeout,click;
extern SHORT palette[];
extern struct Gadget ncp[];
extern struct Image cri[];
extern struct Requester newcolorrequest;
SHORT gadgetid;
SHORT primarytextpen, secondarytextpen;
SHORT undo_code; /* keep track of what done, so may undo correctly */
extern APTR address;
BYTE *errorstring;
#define NUMBER_OF_FRAMES 9 /* temporary limit */
#define MOVELEFT 0
#define MOVERIGHT 1
#define MOVEUP 2
#define MOVEDOWN 3
#define MOVEEND 4
/* *********************undo codes ************************ */
#define FRAME_CLEAR 1
#define COPY_FROM 2
#define MOVEIT 3
#define MERGE_WITH 4
#define SNAPSHOT 5
#define ANIMATE 6
NoEvent() { code = -1; class = -1; qualifier = -1; return(0); }
SHORT testcode;
SHORT savemode; /* TRUE for save, FALSE for load */
HandleEvent()
{
testcode = TRUE; /* closewindow test for neil */
anotherpass:
switch(class)
{
case CLOSEWINDOW:
return(FALSE);
break;
case MOUSEBUTTONS:
if ( code == IECODE_LBUTTON )
doclick(w->MouseX,w->MouseY);
break;
case GADGETUP:
gadgetid = ((struct Gadget *)address)->GadgetID;
if( gadgetid == DISKRWGADGETS) /* cancel */
{
NoEvent();
break;
}
if( gadgetid == TEXTWRITEGADGETS) /* do write */
{
textwrite();
NoEvent();
break;
}
if( gadgetid == TEXTWRITEGADGETS+3) /* do mode */
{
textmode();
NoEvent();
break;
}
if( gadgetid == TEXTWRITEGADGETS+2) /* do style */
{
textstyle();
NoEvent();
break;
}
/* (+1 is cancel, +4 is proportional, ignore till
* the write command actually occurs
*/
else if( gadgetid == DISKRWGADGETS+1) /* load or
* save */
{
performdiskstuff();
NoEvent();
break;
}
else
{
NoEvent();
break;
}
NoEvent();
break;
case GADGETDOWN:
gadgetid = ((struct Gadget *)address)->GadgetID;
if( gadgetid >= MOVEGADGETS &&
gadgetid <= (MOVEGADGETS+4) )
{
moveit(gadgetid);
NoEvent();
break;
}
else if( gadgetid >= COLORGADGETS &&
gadgetid <= COLORGADGETS+31)
{
resetcolor(gadgetid-COLORGADGETS);
NoEvent();
break;
}
else if( gadgetid >= TEXTCOLORGADGETS &&
gadgetid <= TEXTCOLORGADGETS+31)
{
textcolorfix(gadgetid);
NoEvent();
break;
}
else if( gadgetid >= SLIDERGADGETS &&
gadgetid <= SLIDERGADGETS+2)
{
syscolorfix(gadgetid - SLIDERGADGETS);
goto anotherpass;
/* while in syscolorfix, we will
* read events from Intuition.
* Cannot do NoEvent() here since
* we have, within the HandleEvent
* routine itself, have trapped a
* message which must be handled.
* Therefore make "anotherpass" at
* the message handling, since the
* user stopped playing with the
* original color-change gadget
* and has either selected a new
* color change or a different
* gadget entirely
*/
break;
}
else
{
NoEvent();
break;
}
NoEvent();
break;
case MENUPICK:
mode = ITEMNUM(code); /* decode the command */
switch (MENUNUM(code)) {
case 0: /* color */
if ( ITEMNUM(code) == palette[DEPTH-1])
{
changecolor();
NoEvent();
break;
}
else
{
SetAPen( rp, ITEMNUM(code) );
NoEvent();
break;
}
case 1: /* copy */
switch( ITEMNUM(code)) {
case 0: /* undo */
undo();
NoEvent();
break;
case 1: /* scroll */
snapshot();
NoEvent();
break;
case 2: /* from-frame */
copyfrom();
NoEvent();
break;
case 3: /* merge */
mergewith();
default:
NoEvent();
break;
}
break;
case 2: /* move */
switch( ITEMNUM(code)) {
case 0: /* animate */
animate();
NoEvent();
break;
case 1: /* in-frame */
move();
NoEvent();
break;
case 2: /* exchange */
exchange();
default:
NoEvent();
break;
}
break;
case 3: /* text */
switch( ITEMNUM(code)) {
case 0: /* mode */
textdraw(); /* requester */
NoEvent();
break;
case 1: /* style */
textcolor(); /* requester */
default:
NoEvent();
break;
}
case 4: /* disk */
switch( ITEMNUM(code)) {
case 0: /* save */
save();
NoEvent();
break;
case 1: /* load */
load();
NoEvent();
break;
case 2: /* done */
done();
default:
NoEvent();
break;
}
case 5: /* misc */
switch( ITEMNUM(code)) {
case 0: /* clear */
help();
NoEvent();
break;
case 1: /* help */
clear();
NoEvent();
break;
case 2: /* scroll */
scroll();
NoEvent();
break;
case 3: /* reconfig */
reconfigure();
NoEvent();
break;
case 4: /* reconfig */
leave();
default:
NoEvent();
break;
}
default:
break;
}
default:
break;
}
return(testcode);
}
leave(){ /* later must provide an 'are you sure???' */
testcode = FALSE;
return(0);
}
changecolor()
{
Request(&newcolorrequest,w);
return(0);
}
APTR oldaddress;
syscolorfix(whichpart)
SHORT whichpart;
{
SHORT r,g,b;
struct ColorMap *c;
SHORT currentcolor;
c = vp->ColorMap;
currentcolor = GetRGB4(c,color_being_modified);
r = (currentcolor >> 8) & 0xf;
g = (currentcolor >> 4) & 0xf;
b = (currentcolor) & 0xf;
oldaddress = address;
while( waiting_for_different_gadget())
{
switch(whichpart)
{
case MODIFYRED:
SetRGB4(vp,color_being_modified,getvalue(),g,b);
break;
case MODIFYGREEN:
SetRGB4(vp,color_being_modified,r,getvalue(),b);
break;
case MODIFYBLUE:
SetRGB4(vp,color_being_modified,r,g,getvalue());
break;
default:
break;
}
}
return;
}
getvalue() /* address points to the proportional gadget which is down */
{
struct PropInfo *p;
struct Gadget *g;
g = (struct Gadget *)address;
p = (struct PropInfo *)(g->SpecialInfo);
return( (p->HorizPot & 0xf000) >> 12); /* read the pot value and
* return it for color
* modifications
*/
}
resetcolor(id)
SHORT id;
/* make the sliders jump out to the RGB values for the
* color that was selected. In a different loop,
* watch the value of the sliders and do a SetRGB4
* with the values found until requester goes away
*/
{
USHORT rpercent, gpercent, bpercent;
struct ColorMap *c;
color_being_modified = id;
EndRequest(&newcolorrequest,w);
/* get rid of the requester to stop multi-flash when
* modify prop is done
*/
/* change the color of the box at the top of the requester */
cri[palette[ DEPTH - 1]].PlaneOnOff = id & 0x1f;
c = vp->ColorMap;
/* ******************************************* out temporarily
ModifyProp(&colorgadget[0],w,&newcolorrequest,FREEHORIZ,
(GetRGB4(c,id) <<4) &0xf000, 0,0,0);
ModifyProp(&colorgadget[1],w,&newcolorrequest,FREEHORIZ,
(GetRGB4(c,id) <<8) &0xf000, 0,0,0);
ModifyProp(&colorgadget[2],w,&newcolorrequest,FREEHORIZ,
(GetRGB4(c,id) <<12) &0xf000, 0,0,0);
************************************************************************ */
/* prop gadget to modify, pointer to window, pointer to req,
flags, new horizontal, new vertical, hbody, vbody */
myslider[0].HorizPot = 0x1111 * ((GetRGB4(c,id) >> 8) & 0xf);
/* convert 4 bits into 16 bits by
* replicating it in all 4 positions
*/
myslider[1].HorizPot = 0x1111 * ((GetRGB4(c,id) >> 4) & 0xf);
myslider[2].HorizPot = 0x1111 * ((GetRGB4(c,id) ) & 0xf);
/* got new colors, can now redraw the requester */
Request(&newcolorrequest,w);
/* out
RefreshGadgets(&colorgadget[0],w,&newcolorrequest);
*/
return(0);
}
reconfigure(){ return(0);}
textwrite()
{
LONG temp1, temp2;
SHORT error;
SHORT length,length2;
UBYTE *s;
struct Font *oldfontsave;
temp1 = ((textslider.HorizPot >> 8) * (framewidth)) >> 8;
temp2 = ((textslider.VertPot >> 8) * (frameheight-7)) >> 8;
Move(rp,f[selected].xmin + temp1, f[selected].ymin+6+temp2);
length = (framewidth - temp1)/10; /* how many characters fit */
if (length <= 0) return(0);
s = &textstring[0];
length2 = 0;
while(*s++ != '\0') length2++;
length = (length > length2 ? length2 : length);
/* draw only as much text as will fit and no more */
if(txmode == 1)
SetDrMd(rp,JAM1);
else
SetDrMd(rp,JAM2);
if(txfont == 80)
modfontattr.ta_YSize = TXHEIGHT80;
else
modfontattr.ta_YSize = TXHEIGHT60;
oldfontsave = rp->Font; /* save current intuition font */
myfontptr = OpenFont(&modfontattr); /* select what user asks */
if(myfontptr == 0) {
printf("\font wont open");
return(0);
} /* dont draw text if font not found */
SetFont(rp,myfontptr);
/* if (error != 0) {
printf("\nSetFont didnt");
return(0);
}
*/
/* dont draw text if font is bad */
Text(rp,&textstring[0],length);
SetFont(rp,oldfontsave); /* restore old font */
CloseFont(myfontptr);
return(0);
}
textdraw()
{
Request(&textrequest,w);
return(0);
}
textstyle()
{
if( trg[1].GadgetText == &textreqtext[7])
{
trg[1].GadgetText = &textreqtext[8];
txmode = 2;
}
else if(trg[1].GadgetText == &textreqtext[8])
{
trg[1].GadgetText = &textreqtext[7];
txmode = 1;
}
RefreshGadgets(&trg[1],w,&textrequest);
}
textmode()
{
if( trg[2].GadgetText == &textreqtext[9])
{
trg[2].GadgetText = &textreqtext[10];
txfont = 60;
}
else if(trg[2].GadgetText == &textreqtext[10])
{
trg[2].GadgetText = &textreqtext[9];
txfont = 80;
}
RefreshGadgets(&trg[1],w,&textrequest);
}
textcolorfix(id)
SHORT id;
{
if( settxcolor == SETPRIMARY )
primarytextpen = id - TEXTCOLORGADGETS;
else
secondarytextpen = id - TEXTCOLORGADGETS;
return(0);
}
textcolor(){return(0);} /* brings up a requester only */
scroll(){return(0);}
init_animtimer()
{
return(OpenDevice(TIMERNAME,UNIT_VBLANK,animtimermsg,0));
}
set_animtimer(sec,micro)
ULONG sec,micro;
{
animtimermsg->io_Command = TR_ADDREQUEST;
/* add a new timer request */
animtimermsg->SECONDS = sec; /* seconds */
animtimermsg->MICROSECONDS = micro; /* microseconds */
SendIO( animtimermsg ); /* post a request to the timer */
return(0);
}
animate()
{
SHORT n;
SHORT currentselect; /* just for faking out the undo code */
undo_code = ANIMATE;
save_in_undo(0);
animtimerport = CreatePort(0,0);
animtimermsg = CreateStdIO(animtimerport);
init_animtimer();
for(n=0; n<9; n++)
{
ClipBlit(rp, /* source rastport */
f[n].xmin, /* source location x and y */
f[n].ymin,
rp, /* destination rastport */
f[0].xmin,
f[0].ymin,
framewidth, /* bit-size of rectangle */
frameheight,
0xc0); /* c0 means bit-for bit in all planes */
set_animtimer(0,333333); /* 1/3 second between animates */
Wait( 1 << animtimerport->mp_SigBit); /* wait for timeout */
GetMsg( animtimerport );
/* remove the message after the wait */
}
currentselect = selected;
selected = 0; /* not really selected, just for undo
* so that frame 0 is restored to screen
* at the end of the animation
*/
undo();
selected = currentselect;
CloseDevice(animtimermsg);
DeleteStdIO(animtimermsg);
DeletePort(animtimerport);
return(0);
}
snapshot()
{
undo_code = SNAPSHOT;
save_in_undo(selected);
return(0);
}
help(){return(0);}
done(){return(0);}
/* only change to Event.c ... activate save request */
save()
{
dostext[1].IText = (UBYTE *)"SAVE";
Request(&dosrequest,w);
savemode = TRUE;
return(0);
}
load()
{
dostext[1].IText = (UBYTE *)"LOAD";
Request(&dosrequest,w);
savemode = FALSE;
return(0);
}
performdiskstuff()
{
if(savemode)
dodisksave();
else
dodiskload();
return(0);
}
dodisksave()
{
UWORD n,i,j;
struct saveformat s;
ULONG length;
UBYTE *p; /* pointer to data */
/* first open the file for save ... if it exists, for now,
* refuse to do it. (later bring up a requester that asks
* if you want to replace it)
*/
s.next = 0;
s.depth = DEPTH; /* system global variable */
s.width = framewidth;
s.height = frameheight;
s.colorset = sizeof(struct saveformat)-2;
/* store colors first */
s.dataset = s.colorset + ((palette[DEPTH-1])<<1);
/* start data storage immediately after the colors */
/* each color listed in palette[depth-1] takes 2
* bytes to store in the disk file */
file = Open( &dosname[0], MODE_NEWFILE );
if (file == 0 )
/* couldnt open as a new file */
{
errorstring = "\nFile Already Exists, Choose A New Name";
printf(errorstring);
return(0);
}
printf("file open for save\n");
/* SAVE THE DATA DESCRIPTOR */
length = sizeof(struct saveformat)-2;
/* how many bytes to write on first save */
actual_len = Write( file, &s, length );
if (actual_len != length )
goto write_error;
printf("saved the data descriptor\n");
/* SAVE THE COLOR PALETTE */
length = (palette[DEPTH-1])<<1; /* two bytes per word */
actual_len = Write( file, vp->ColorMap->ColorTable, length);
if(actual_len != length)
goto write_error;
printf("saved the color palette\n");
/* TEMPORARY LIMIT OF 9 frames */
length = ((framewidth+15)>>4)<<1; /* calculate words,
* save as bytes
* (dos writes bytes) */
for(n=0; n<NUMBER_OF_FRAMES; n++)
{ /* copy to bit/word align in small rastport */
ClipBlit(rp, /* source rastport */
f[n].xmin, /* source location x and y */
f[n].ymin,
&smallrastport, /* small rastport destination rastport */
0, /* destination x and y */
0,
framewidth, /* bit-size of rectangle */
frameheight,
0xc0); /* c0 means bit-for bit in all planes */
for(i=0; i<BOBDEPTH; i++)
{
p = smallbitmap.Planes[i];
for(j=0; j<frameheight; j++)
{
actual_len = Write(file, p, length); if(actual_len != length) goto write_error;
p += smallbitmap.BytesPerRow;
}
}
printf("saved one frame\n");
}
Close(file);
return(0);
write_error:
Close (file);
errorstring = "Error While Trying To Write";
/* bring up a requester to tell user about the error */
/* FUTURE */
return(0);
}
dodiskload()
{
UWORD n,i,j;
struct saveformat s;
ULONG length;
UWORD colorstoload[32];
UBYTE *p; /* pointer to data */
/* first open the file for load ... if it doesnt exist, for now,
* refuse to do it. (later bring up a requester that asks
* for a different name)
*/
file = Open( &dosname[0], MODE_OLDFILE );
if (file == 0 )
/* couldn't open the file */
{
errorstring = "\nFile Not Found Or Unknown Error";
printf(errorstring);
return(0);
}
printf("opened for read\n");
/* READ THE SAVEFORMAT info */
length = (sizeof(struct saveformat)-2);
actual_len = Read( file, &s, length);
if (actual_len != length) goto read_error;
/* first pass assumes everything is ok as to where data is going */
printf("read the load-format\n");
/* READ AND LOAD THE COLOR INFO */
if( s.colorset != 0 )
{
Seek( file, s.colorset, OFFSET_BEGINING);
/* seek to where in the file the color set starts */
length = (palette[s.depth-1])<<1;
actual_len = Read( file, &colorstoload[0], length);
if (actual_len != length) goto read_error;
LoadRGB4(vp, &colorstoload[0], palette[s.depth-1]);
}
printf("read and loaded the colors\n");
if( s.dataset != 0 )
{
Seek( file, s.dataset, OFFSET_BEGINING);
/* seek to where in the file the color set starts */
length = ((framewidth+15)>>4)<<1;
for(n=0; n<NUMBER_OF_FRAMES; n++)
{ /* copy to bit/word align in small rastport */
for(i=0; i<BOBDEPTH; i++)
{
p = smallbitmap.Planes[i];
for(j=0; j<frameheight; j++)
{
actual_len = Read(file, p, length);
if(actual_len != length) goto read_error;
p += smallbitmap.BytesPerRow;
}
}
ClipBlit(&smallrastport,
0, /* destination x and y */
0,
rp, /* source rastport */
f[n].xmin, /* source location x and y */
f[n].ymin,
framewidth, /* bit-size of rectangle */
frameheight,
0xc0); /* c0 means bit-for bit in all planes */
printf("read and loaded a frame\n");
}
Close(file);
return(0);
}
read_error:
errorstring = "Error While Trying To Read";
/* bring up a requester to tell user about this */
Close(file);
return(0);
}
save_in_undo(n)
SHORT n;
{
ClipBlit(rp, /* source rastport */
f[n].xmin, /* source location x and y */
f[n].ymin,
&undorastport, /* undo rastport destination rastport */
0, /* destination x and y */
0,
framewidth, /* bit-size of rectangle */
frameheight,
0xc0); /* c0 means bit-for bit in all planes */
return(0);
}
move() /* just brings up a requester */
{
Request( &myrequest, w);
return(0);
}
moveit(where)
SHORT where;
{
switch(where) {
case MOVELEFT:
moveitsub(-1,0);
break;
case MOVERIGHT:
moveitsub(1,0);
break;
case MOVEUP:
moveitsub(0,-1);
break;
case MOVEDOWN:
moveitsub(0,1);
break;
case MOVEEND:
doexpand(selected);
break;
}
return(0);
}
moveitsub(x,y)
SHORT x,y;
{
/* move it a distance in the x and y direction */
SHORT width, height;
SHORT xsrc, ysrc;
SHORT xdest, ydest;
SHORT oldpen;
if( x == 0 )
{
height = frameheight - 1;
width = framewidth;
xsrc = 0;
xdest = f[selected].xmin;
if( y < 0)
{
ydest = f[selected].ymin; /* move up */
ysrc = 1;
}
else
{
ydest = f[selected].ymin+1; /* move down */
ysrc = 0;
}
}
if( y == 0 )
{
height = frameheight;
width = framewidth - 1;
ysrc = 0;
ydest = f[selected].ymin;
if( x < 0)
{
xdest = f[selected].xmin; /* move left */
xsrc = 1;
}
else
{
xdest = f[selected].xmin+1; /* move right */
xsrc = 0;
}
}
save_in_undo(selected); /* save the selected one in undo */
undo_code = MOVEIT;
ClipBlit(&undorastport, /* undo = source rastport */
xsrc, /* source x and y */
ysrc,
rp, /* undo rastport destination rastport */
xdest, /* destination x and y */
ydest,
width, /* bit-size of rectangle */
height,
0xc0); /* c0 means bit-for bit in all planes */
oldpen = rp->FgPen;
SetAPen(rp,0); /* going to adjust edges after move */
if(x == 0)
switch(ysrc)
{
case 0: Move(rp,f[selected].xmin,f[selected].ymin);
Draw(rp,f[selected].xmax,f[selected].ymin);
break;
case 1: Move(rp,f[selected].xmin,f[selected].ymax);
Draw(rp,f[selected].xmax,f[selected].ymax);
break;
}
if(y == 0)
switch(xsrc)
{
case 0: Move(rp,f[selected].xmin,f[selected].ymin);
Draw(rp,f[selected].xmin,f[selected].ymax);
break;
case 1: Move(rp,f[selected].xmax,f[selected].ymin);
Draw(rp,f[selected].xmax,f[selected].ymax);
break;
}
SetAPen(rp,oldpen);
return(0);
}
clear() /* clear the selected window, but save the image in the
* undo buffer so user can restore it if he wants to */
{
SHORT n,oldpen;
undo_code = FRAME_CLEAR;
n = selected; /* can only clear the selected frame */
save_in_undo(n);
/* now clear it */
oldpen = rp->FgPen;
SetAPen(rp, 0);
RectFill(rp, f[n].xmin, f[n].ymin, f[n].xmax, f[n].ymax );
SetAPen(rp,oldpen);
erase_edit(); /* selected one is displayed, so clear
* there also */
return(0);
}
copyfrom() /* copy from specified frame into selected frame */
{
SHORT n;
undo_code = COPY_FROM;
n = SUBNUM(code);
save_in_undo(selected); /* save old contents */
ClipBlit(rp, /* source rastport */
f[n].xmin, /* source location x and y */
f[n].ymin,
rp, /* destination rastport */
f[selected].xmin,
f[selected].ymin,
framewidth, /* bit-size of rectangle */
frameheight,
0xc0); /* c0 means bit-for bit in all planes */
doexpand(selected);
return(0);
}
mergewith() /* Merge data from specified into selected frame */
{
SHORT n;
undo_code = MERGE_WITH;
n = SUBNUM(code);
save_in_undo(selected); /* save old contents */
ClipBlit(rp, /* source rastport */
f[n].xmin, /* source location x and y */
f[n].ymin,
rp, /* destination rastport */
f[selected].xmin,
f[selected].ymin,
framewidth, /* bit-size of rectangle */
frameheight,
0xe0); /* e0 means 'OR' the contents */
doexpand(selected);
return(0);
}
exchange()
{
SHORT n;
n = SUBNUM(code);
copyfrom();
undo_code = 0; /* to undo an exchange, simply exchange */
ClipBlit(&undorastport, /* source rastport */
0, /* source location x and y */
0,
rp, /* destination rastport */
f[n].xmin,
f[n].ymin,
framewidth, /* bit-size of rectangle */
frameheight,
0xc0); /* c0 means bit-for bit in all planes */
doexpand(selected);
return(0);
}
undo()
{
switch(undo_code) {
case FRAME_CLEAR:
case COPY_FROM:
case MOVEIT:
case SNAPSHOT:
case MERGE_WITH:
case ANIMATE:
ClipBlit(&undorastport, /* source rastport */
0, /* source location x and y */
0,
rp, /* destination rastport */
f[selected].xmin,
f[selected].ymin,
framewidth, /* bit-size of rectangle */
frameheight,
0xc0); /* bit-for bit all planes */
break;
default:
break;
}
doexpand(selected);
return(0);
}